﻿using System;
using Nancy;

namespace GeometryServer.Modules
{
    //http://localhost:13775/rest/services/Geometry/GeometryServer/union?sr=102113&geometries={"geometryType":"GeometryMultipoint","spatialReference":{"wkid":102113},"geometries":[{"points":[[-8418433.3989,5262954.0867],[-8353363.717800001,5381714.5528],[-8250336.7228,5337002.1307],[-8250336.7228,5509587.154700004]]},{"points":[[-1.37211748048E7,4991906.4582],[-1.35126474057E7,4800770.159900002],[-1.35126474057E7,4991906.4582],[-1.3470941925900001E7,4468209.699000001],[-1.32936936367E7,4494424.728500001],[-1.31998563072E7,4133116.2506000027],[-1.3126871717500001E7,4260779.642999999],[-1.29391970583E7,4044613.1774000004],[-1.29183443184E7,4222325.328299999],[-1.28870652086E7,3906909.467299998]]}]}
    public class UnionModule : NancyModule
    {
        public UnionModule()
            : base("/rest/services/Geometry/GeometryServer/")
        {
            Get["/union"] = parameters =>
            {
                var model = new Models.Union();

                var exception = new GISServer.Core.Exception();
                exception.Error = new GISServer.Core.Error
                {
                    Code = 400,
                    Message = "Unable to complete union operation."
                };


                #region Parameter

                if (Request.Query["f"].Value == "json")
                {
                    model.Format = Request.Query["f"].Value;
                }
                else
                {
                    model.Format = "HTML";
                }


                if (Request.Query["geometries"].Value != null)
                {
                    model.InputGeometries = Request.Query["geometries"].Value;
                }


                if (Request.Query["sr"].Value != null)
                {
                    int value;
                    var successful = int.TryParse(Request.Query["sr"].Value, out value);
                    if (successful)
                    {
                        model.InputSpatialReference = value;
                    }
                    else
                    {
                        if (!model.HasException)
                        {
                            model.HasException = true;
                        }
                        exception.Error.Details.Add("'sr' parameter is invalid");
                    }
                }

                #endregion
                var output_sing_geom = new GISServer.Core.Client.Geometry.SingleGeometry();

                if ((model.InputGeometries != null) && (!model.HasException))
                {
                    try
                    {
                        var input_geom_array = new GISServer.Core.Client.Geometry.GeometryArray();
                        input_geom_array = GISServer.Core.Client.Utilities.Parser.GetGeometies(model.InputGeometries);
                        var dotspatial_geom_array = Services.Utilities.getDotSpatialGeometryArray(input_geom_array);

                        var dotspatial_igeometry = Services.Compute.Union(dotspatial_geom_array);
                        var server_geom_array = Services.Utilities.GetGISSingleGeometry(dotspatial_igeometry);

                        
                        output_sing_geom = server_geom_array;
                    }
                    catch (Exception)
                    {
                        if (!model.HasException)
                        {
                            model.HasException = true;
                        }
                        exception.Error.Details.Add("Unable to union the geometries");
                    }
                }

                if (!model.HasException)
                {
                    model.Result = output_sing_geom.ToJson();
                }
                else
                {
                    model.Exception = exception.ToJson();
                }


                if (model.Format.Equals("json"))
                {
                    if (!model.HasException)
                    {
                        return Services.Utilities.GetJsonResponseObject(model.Result);
                    }
                    else
                    {
                        return Services.Utilities.GetJsonResponseObject(model.Exception);
                    }

                }
                else
                {
                    return View["Union", model];
                }
            };

        }
    }
}